package com.zmzncs.lmtc.module.promotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmzncs.lmtc.common.util.ExceptionUtil;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.park_info.ParkInfoDTO;
import com.zmzncs.lmtc.module.promotion.dao.DurationRuleFeeScaleMapper;
import com.zmzncs.lmtc.module.promotion.dao.DurationRuleMapper;
import com.zmzncs.lmtc.module.promotion.dao.DurationRuleParkMapper;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule.*;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule_fee_scale.DurationRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule_park.DurationRulePark;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule_fee_scale.DurationRuleFeeScale;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule_fee_scale.DurationRuleFeeScaleForm;
import com.zmzncs.lmtc.module.promotion.pojo.duration_rule_park.DurationRuleParkDTO;
import com.zmzncs.lmtc.module.promotion.service.DurationRuleFeeScaleService;
import com.zmzncs.lmtc.module.promotion.service.DurationRuleParkService;
import com.zmzncs.lmtc.module.promotion.service.DurationRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 促销-时长规则 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-08-12
 */
@Service
@Slf4j
public class DurationRuleServiceImpl extends ServiceImpl<DurationRuleMapper, DurationRule> implements DurationRuleService {


    @Autowired
    DurationRuleMapper durationRuleMapper;
    @Autowired
    DurationRuleParkMapper durationRuleParkMapper;
    @Autowired
    DurationRuleFeeScaleMapper durationRuleFeeScaleMapper;
    @Autowired
    private ParkInfoDao parkInfoDao;
    @Autowired
    DurationRuleFeeScaleService durationRuleFeeScaleService;
    @Autowired
    DurationRuleParkService durationRuleParkService;

    /**
     * 添加促销时长规则类型
     */
    @Override
    @Transactional
    public void addDurationRule(DurationRuleAddForm form) {
        List<DurationRuleDTO> durationRuleByNameList = durationRuleMapper.getDurationRuleByName(form.getRuleName());
        if(durationRuleByNameList.size() > 0){
            ExceptionUtil.businessException("规则名称【" + form.getRuleName() + "】已存在");
        }

        //  已有规则的停车场
        List<DurationRulePark> durationRuleParkList = durationRuleParkMapper.selectList(null);
        List<Long> hasRuleParkIdList = durationRuleParkList.stream().map(DurationRulePark::getParkId).collect(Collectors.toList());

        //  校验停车场是否已经有其他时长规则
        for(Long parkId: form.getParkIds()){
            if(hasRuleParkIdList.contains(parkId)){
                ExceptionUtil.businessException("停车场id为" + parkId + "的停车场已经有其他时长规则");
            }
        }

        //  如果匹配所有停车场，查询所有停车场id集合
        if(form.getIfAllParks().equals(1)){
            if(durationRuleParkList.size() != 0){
                ExceptionUtil.businessException("已有停车场存在规则，全部停车场不可选");
            }
            //  查询所有停车场
            List<ParkInfoDTO> parkInfoDTOList = parkInfoDao.getParks();
            List<Long> parkIdList = parkInfoDTOList.stream().map(ParkInfoDTO::getId).collect(Collectors.toList());
            form.setParkIds(parkIdList);
        }

        //  添加时长规则
        DurationRule durationRule = new DurationRule();
        BeanUtils.copyProperties(form, durationRule);
        durationRuleMapper.insert(durationRule);

        //  添加时长规则的停车场
        List<DurationRulePark> addDurationRuleParkList = new ArrayList<>();
        for(Long parkId: form.getParkIds()){
            DurationRulePark durationRulePark = new DurationRulePark();
            durationRulePark.setDurationRuleId(durationRule.getId());   //  时长规则id
            durationRulePark.setParkId(parkId); //  停车场id
            addDurationRuleParkList.add(durationRulePark);
        }
        durationRuleParkService.saveBatch(addDurationRuleParkList);

        //  添加时长规则的收费标准
        List<DurationRuleFeeScale> addDurationRuleFeeScaleList = new ArrayList<>();
        for(DurationRuleFeeScaleForm durationRuleFeeScaleForm : form.getMonthRentTypes()){
            DurationRuleFeeScale durationRuleFeeScale = new DurationRuleFeeScale();
            durationRuleFeeScale.setDurationRuleId(durationRule.getId());   //  时长规则id
            durationRuleFeeScale.setAmount(durationRuleFeeScaleForm.getAmount()); //  金额
            durationRuleFeeScale.setDuration(durationRuleFeeScaleForm.getDuration()); //  时长（小时）
            addDurationRuleFeeScaleList.add(durationRuleFeeScale);
        }
        durationRuleFeeScaleService.saveBatch(addDurationRuleFeeScaleList);
    }

    /**
     * 修改促销时长规则
     */
    @Override
    @Transactional
    public void updateDurationRule(DurationRuleUpdateForm form) {
        List<DurationRuleDTO> durationRuleByNameList = durationRuleMapper.getDurationRuleByName(form.getRuleName());
        if(durationRuleByNameList.size() > 0){
            List<Long> durationRuleIdList = durationRuleByNameList.stream().map(DurationRuleDTO::getId).collect(Collectors.toList());
            if(!durationRuleIdList.contains(form.getId())){
                ExceptionUtil.businessException("规则名称【" + form.getRuleName() + "】已存在");
            }
        }

        //  查询某时长规则之外的停车场
        List<DurationRuleParkDTO> durationRuleParkDTOList = durationRuleParkMapper.getDurationRuleExcludeParkList(form.getId());
        //  其他已有规则的停车场id集合
        List<Long> otherRuleParkIdList = durationRuleParkDTOList.stream().map(DurationRuleParkDTO::getParkId).collect(Collectors.toList());

        //  校验停车场是否已经有其他时长规则
        for(Long parkId: form.getParkIds()){
            if(otherRuleParkIdList.contains(parkId)){
                ExceptionUtil.businessException("停车场id为" + parkId + "的停车场已经有其他时长规则");
            }
        }

        //  如果匹配所有停车场，查询所有停车场id集合
        if(form.getIfAllParks().equals(1)){
            Integer durationRuleParkCount = durationRuleParkMapper.selectCount(null);
            if(durationRuleParkCount > 0){
                ExceptionUtil.businessException("已有停车场存在规则，全部停车场不可选");
            }
            //  查询所有停车场
            List<ParkInfoDTO> parkInfoDTOList = parkInfoDao.getParks();
            List<Long> parkIdList = parkInfoDTOList.stream().map(ParkInfoDTO::getId).collect(Collectors.toList());
            form.setParkIds(parkIdList);
        }

        //  修改时长规则
        DurationRule durationRule = new DurationRule();
        BeanUtils.copyProperties(form, durationRule);
        durationRuleMapper.updateById(durationRule);

        //*********************修改停车场
        //  删除旧的停车场数据
        LambdaUpdateWrapper<DurationRulePark> durationRuleParkWrapper = new LambdaUpdateWrapper();
        durationRuleParkWrapper.eq(DurationRulePark::getDurationRuleId, form.getId());
        durationRuleParkMapper.delete(durationRuleParkWrapper);
        //  添加新的时长规则的停车场
        List<DurationRulePark> addDurationRuleParkList = new ArrayList<>();
        for(Long parkId: form.getParkIds()){
            DurationRulePark durationRulePark = new DurationRulePark();
            durationRulePark.setDurationRuleId(durationRule.getId());   //  时长规则id
            durationRulePark.setParkId(parkId); //  停车场id
            addDurationRuleParkList.add(durationRulePark);
        }
        durationRuleParkService.saveBatch(addDurationRuleParkList);

        //  *******************收费标准
        //  删除旧的收费标准
        LambdaUpdateWrapper<DurationRuleFeeScale> durationRulePaytypeWrapper = new LambdaUpdateWrapper();
        durationRulePaytypeWrapper.eq(DurationRuleFeeScale::getDurationRuleId, form.getId());
        durationRuleFeeScaleMapper.delete(durationRulePaytypeWrapper);
        //  添加新的时长规则的收费标准
        List<DurationRuleFeeScale> addDurationRuleFeeScaleList = new ArrayList<>();
        for(DurationRuleFeeScaleForm durationRuleFeeScaleForm : form.getMonthRentTypes()){
            DurationRuleFeeScale durationRuleFeeScale = new DurationRuleFeeScale();
            durationRuleFeeScale.setDurationRuleId(durationRule.getId());   //  时长规则id
            durationRuleFeeScale.setAmount(durationRuleFeeScaleForm.getAmount()); //  金额
            durationRuleFeeScale.setDuration(durationRuleFeeScaleForm.getDuration()); //  时长（小时）
            addDurationRuleFeeScaleList.add(durationRuleFeeScale);
        }
        durationRuleFeeScaleService.saveBatch(addDurationRuleFeeScaleList);
    }

    /**
     * 查询时长规则列表
     */
    @Override
    public IPage<DurationRuleDTO> getDurationRuleList(Page page, String keyword) {
        IPage<DurationRuleDTO> durationRulePage = durationRuleMapper.getDurationRuleList(page, keyword);
        //  收费标准
        for(DurationRuleDTO ruleDTO: durationRulePage.getRecords()){
            //  查询规则的收费标准
            List<DurationRuleFeeScaleDTO> durationRuleFeeScaleDTOList = durationRuleFeeScaleMapper.getDurationRuleFeeScaleByRuleId(ruleDTO.getId());
            ruleDTO.setFeeScaleList(durationRuleFeeScaleDTOList);
        }
        return durationRulePage;
    }

}
